package com.ke.rule.base;

import com.google.common.collect.Maps;

import java.util.Map;

/**
 * service method context
 * 
 * @author guyu
 */
public class ServiceMethodContext {
  // 返回结果的Key值
  public static final String RETURN_RESULT = "RETURN_RESULT";

  // method implements
  protected final DecisionBasedServiceMethod<?> methodImpl;
  
  // associated variables
  private final Map<String, Object> variables;
  
  public ServiceMethodContext(DecisionBasedServiceMethod<?> methodImpl) {
    super();
    this.methodImpl = methodImpl;
    this.variables = Maps.newHashMap();
  }
  
  public String getMethodId() {
    return methodImpl.getId();
  }

  public DecisionBasedServiceMethod<?> getMethodImpl() {
    return methodImpl;
  }

  public boolean isFuncUnitBillCacheable() {
    return methodImpl.isFuncUnitBillCacheable(methodImpl.getCurrentStepType());
  }
  
  public IApplicationService getService() {
    return methodImpl.getService();
  }

  public MethodStepType getCurrentStepType() {
    return methodImpl.getCurrentStepType();
  }

  /**
   * 获取入参对象(处理过程中可能会被修改)
   * @return
   */
  public Object getValue() {
    return methodImpl.getValue();
  }

  public void setValue(Object value) {
    methodImpl.setValue(value);
  }
  
  /**
   * 获取未被修改的入参对象
   * @return
   */
  public Object getRawValue() {
    return methodImpl.getRawValue();
  }
  
  /**
   * 获取修改前的入参对象
   * @return
   */
  public Object getOldValue() {
    return methodImpl.getOldValue();
  }

  public void setOldValue(Object oldValue) {
    methodImpl.setOldValue(oldValue);
  }
  
  public Map<String, Object> getVariables() {
    return variables;
  }

  /**
   * 线程内的方法间调用的共享Key
   * @param key
   * @return
   */
  private String sharedKey(String key) {
    return String.format("%s.intermethod_shared", key);
  }
  
  /**
   * 方法内变量
   * @param key
   * @param value
   */
  public void put(String key, Object value) {
    variables.put(key, value);
  }
  
  /**
   * 方法间共享变量
   * @param key
   * @param value
   */
  public void putToShared(String key, Object value) {
    CacheLocalUtils.set(sharedKey(key), value);
  }
  
  /**
   * 优先从上下文变量中获取，取不到则从线程上下文中读取
   * @param key
   * @return
   */
  public Object get(String key) {
    Object value = variables.get(key);
    if (null == value) {
      value = CacheLocalUtils.get(sharedKey(key));
    }
    return value;
  }
  
  public void clear(String... keys) {
    for (String k : keys) {
      variables.remove(k);
    }
  }

  public void signalToEnd() {
    methodImpl.signalToEnd();
  }
  
  public boolean isEarlyEnd() {
    return methodImpl.isEarlyEnd();
  }
  
  public void setReturnResult(Object result) {
    put(RETURN_RESULT, result);
  }
  
  public Object getReturnResult() {
    return get(RETURN_RESULT);
  }

  /**
   * clean up and release resources
   */
  public void dispose() {
    variables.clear();
  }
  
}
